//node.js modules
import * as  http    from 'http';
import * as https    from 'https';
import {FinchLogger} from 'finch-log';

//other modules
import {
    handles,
    middleWareFunction
}                              from "./interface";
import {createRequestListener} from "./function_createRequestListener";

interface FinchOption
{
    disableLogger?: boolean,
    staticFileDir?: string,
    httpsOption?: {
        key: string,
        cert: string
    }
}


/**
 * 处理HTTP请求的类
 */
class Finch
{

    public StaticDir: string   = undefined;
    public Logger: FinchLogger = new FinchLogger({maxFiles: 200, maxLines: 8000,});
    public Handles: handles    = {};
    public Server: http.Server | https.Server;

    private allFunctions: middleWareFunction[] = [];


    constructor(option: FinchOption)
    {
        if (!option.disableLogger)
        {
            this.Logger = new FinchLogger({
                maxLines     : 8000,
                maxFiles     : 200,
                logStorageDir: './FinchServerLog'
            })
        }
        this.StaticDir = option.staticFileDir;

        if (option.httpsOption)
        {
            //TODO 验证HTTPS服务的正确性
            this.Server = https.createServer(option.httpsOption, createRequestListener(this));
        }
        else
        {
            this.Server = http.createServer(createRequestListener(this));
        }
    }

    /**
     * 监听端口的方法，服务通过此方法启动
     * @param port 端口号
     */
    public listen(port: number): void
    {
        this.Server.listen(port);
        this.Logger.log(`Finch 正在监听端口 ${port}`);
    }

    /**
     * 通过此方法使用中间件
     * @param handle 句柄，通常是请求的路径。
     * @param middleWare 中间件，用来处理逻辑。
     */
    public use(handle: string, middleWare: middleWareFunction): void
    {
        if (!this.Handles.hasOwnProperty(handle))
        {
            this.Handles[handle] = [];
            for (let a in this.allFunctions)
            {
                this.Handles[handle].push(this.allFunctions[a]);
            }
        }
        this.Handles[handle].push(middleWare);
    }

    /**
     * 通过此方法为所有的句柄增加中间件
     * @param middleWare 中间件
     */
    public all(middleWare: middleWareFunction): void
    {
        this.allFunctions.push(middleWare);
        for (let a in this.Handles)
        {
            this.Handles[a].push(middleWare);
        }
    }
}


export {Finch}
